package yaner.hotel.manager.resource.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import yaner.hotel.manager.common.dto.menu.MenuAddDto;
import yaner.hotel.manager.common.dto.menu.MenuDto;
import yaner.hotel.manager.common.dto.menu.MenuUpdateDto;
import yaner.hotel.manager.common.vo.MenuVo;
import yaner.hotel.manager.common.vo.SelectOptionVo;
import yaner.hotel.manager.resource.dao.IMenuDao;
import yaner.hotel.manager.resource.entity.Menu;
import yaner.hotel.manager.resource.mapper.IMenuMapper;
import yaner.hotel.manager.resource.service.IMenuService;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements IMenuService {
    private final IMenuDao menuDao;
    private final IMenuMapper menuMapper;
    public MenuServiceImpl(IMenuDao menuDao, IMenuMapper menuMapper) {
        this.menuDao = menuDao;
        this.menuMapper = menuMapper;
    }

    @Override
    public List<MenuVo> menuList(MenuDto menuDto) {
        List<MenuVo> menuVoList = new ArrayList<>();
        List<Menu> menuList = menuDao.selectList(
                new QueryWrapper<Menu>()
                        .lambda()
                        .orderByAsc(Menu::getSortNo)
        );
        Map<String, String> menuListMap = menuList.stream().collect(Collectors.toMap(Menu::getId, Menu::getMenuName));
        menuListMap.put("0", "根菜单");
        menuList.forEach(menu -> {
            MenuVo menuVo = menuMapper.toVo(menu);
            menuVoList.add(menuVo);
            if (StrUtil.isNotBlank(menu.getParentId())) {
                String menuName = menuListMap.get(menu.getParentId());
                menuVo.setParentMenuName(menuName);
            }
        });
        return menuVoList;
    }

    @Override
    public List<SelectOptionVo> selectMenuList(MenuDto menuDto) {
        List<SelectOptionVo> selectOptionVoList = new ArrayList<>();
        List<Menu> menuList = menuDao.selectList(
                new QueryWrapper<Menu>()
                        .lambda()
                        .eq(Menu::getParentId, menuDto.getParentId())
                        .orderByAsc(Menu::getSortNo)
        );
        selectOptionVoList.add(SelectOptionVo.builder().label("根菜单").value("0").build());
        menuList.forEach(menu -> {
            SelectOptionVo selectOptionVo = SelectOptionVo.builder()
                    .label(menu.getMenuName())
                    .value(menu.getId())
                    .build();
            selectOptionVoList.add(selectOptionVo);
        });
        return selectOptionVoList;
    }

    @Override
    public MenuVo getMenuInfo(String menuId) {
        Menu menu = menuDao.selectById(menuId);
        return menuMapper.toVo(menu);
    }

    @Override
    public String addMenuInfo(MenuAddDto menuAddDto) {
        menuAddDto.setSortNo(getSortNo(menuAddDto.getParentId()));
        Menu menu = menuMapper.toAddEntity(menuAddDto);
        int insert = menuDao.insert(menu);
        return String.valueOf(insert);
    }

    private Double getSortNo(String parentId){
        double v = "0".equals(parentId) ? 1 : 0.1;
            List<Menu> menuList = menuDao.selectList(
                    new QueryWrapper<Menu>()
                            .lambda()
                            .eq(Menu::getParentId, parentId)
            );
            List<Menu> list = menuList.stream()
                    .sorted(Comparator.comparingDouble(Menu::getSortNo).reversed())
                    .collect(Collectors.toList());
            return list.get(0).getSortNo() + v;
    }

    @Override
    public String updateMenuInfo(MenuUpdateDto menuUpdateDto) {
        Menu menu = menuMapper.toUpdateEntity(menuUpdateDto);
        int update = menuDao.updateById(menu);
        return String.valueOf(update);
    }

    @Override
    public String deleteMenuInfo(String menuId) {
        int i = menuDao.deleteById(menuId);
        return String.valueOf(i);
    }
}
